uCOS Startup Walk ThroughΒΆ

This is walkthrough of a sample uCOS application. The application has three tasks using two mailboxes.

The walkthrough starts with main follows the sequence of functions the lead to up to the running application.

It’s trimmed down to make it clearer the minimum sequences of steps and calls needed to make the application run.

The first thing that runs is crt.s which sets up the exception mode stacks and handlers. When it’s finshed it jumps to main.

//-------------------------------------------------------------------------------------------------------------------

int main(void)
{
    OSInit();

    err = OSTaskCreate(AppTaskStart,
                      (void*)0,
                      (void*)&StartupStk[APP_TASK_START_STK_SIZE-1],
                      APP_TASK_START_PRIO);

    OSStart();
}

//-------------------------------------------------------------------------------------------------------------------

void  OSInit (void)
{
    OSInitHookBegin();                  /* Call port specific initialization code   */
    OS_InitMisc();                      /* Initialize miscellaneous variables       */
    OS_InitRdyList();                   /* Initialize the Ready List                */
    OS_InitTCBList();                   /* Initialize the free list of OS_TCBs      */
    OS_InitEventList();                 /* Initialize the free list of OS_EVENTs    */
    OS_FlagInit();                      /* Initialize the event flag structures     */
    OS_MemInit();                       /* Initialize the memory manager            */
    OS_QInit();                         /* Initialize the message queue structures  */
    OS_InitTaskIdle();                  /* Create the Idle Task                     */
    OS_InitTaskStat();                  /* Create the Statistic Task                */
    OSTmr_Init();                       /* Initialize the Timer Manager             */
    OSInitHookEnd();                    /* Call port specific init. code            */
    OSDebugInit();
}

//-------------------------------------------------------------------------------------------------------------------

INT8U  OSTaskCreateExt (void (*task)(void *p_arg), void *p_arg, OS_STK *ptos, INT8U prio,
                        INT16U id, OS_STK *pbos, INT32U stk_size, void *pext, INT16U opt)
{
    // Allocate storage for CPU status register
    OS_CPU_SR  cpu_sr = 0;

    OS_ENTER_CRITICAL();

    /* Make sure we don't create the task from within an ISR  */
    if (OSIntNesting > 0)
    {
        OS_EXIT_CRITICAL();
        return (OS_ERR_TASK_CREATE_ISR);
    }

    /* Make sure task doesn't already exist at this priority  */
    /* Reserve the priority to prevent others from doing ...  */
    /* ... the same thing until task is created.              */

    if (OSTCBPrioTbl[prio] == (OS_TCB *)0)
    {
        OSTCBPrioTbl[prio] = OS_TCB_RESERVED;
        OS_EXIT_CRITICAL();

        /* Clear the task stack (if needed)     */
        OS_TaskStkClr(pbos, stk_size, opt);

        // Initialize the task's stack
        psp = OSTaskStkInit(task, p_arg, ptos, opt);
        err = OS_TCBInit(prio, psp, pbos, id, stk_size, pext, opt);

        if (err == OS_ERR_NONE)
        {
            if (OSRunning == OS_TRUE)
            {
                /* Find HPT if multitasking has started */
                OS_Sched();
            }
        }
        else
        {
            OS_ENTER_CRITICAL();
            OSTCBPrioTbl[prio] = (OS_TCB *)0;       /* Make this priority avail. to others  */
            OS_EXIT_CRITICAL();
        }
        return (err);
    }
    OS_EXIT_CRITICAL();

    return (OS_ERR_PRIO_EXIST);
}

//-------------------------------------------------------------------------------------------------------------------

void  OSStart (void)
{
    if (OSRunning == OS_FALSE) {
        OS_SchedNew();                               /* Find highest priority's task priority number   */
        OSPrioCur     = OSPrioHighRdy;
        OSTCBHighRdy  = OSTCBPrioTbl[OSPrioHighRdy]; /* Point to highest priority task ready to run    */
        OSTCBCur      = OSTCBHighRdy;
        OSStartHighRdy();                            /* Execute target specific code to start task     */
    }
}

//-------------------------------------------------------------------------------------------------------------------

static  void  OS_SchedNew (void)
{
    /* Find highest priority task */
}

//-------------------------------------------------------------------------------------------------------------------


OSStartHighRdy:

    // asm code
    // a) Calls OSTaskSwHook()
    // b) Sets OSRunning to TRUE
    // c) Switches to the highest priority task.


//-------------------------------------------------------------------------------------------------------------------

static  void  AppTaskStart (void *p_arg)
{
    /* Create MBOXs for communication between Kbd and UserIF    */
    AppUserIFMbox1 = OSMboxCreate((void *)0);
    AppUserIFMbox2 = OSMboxCreate((void *)0);

    /* Create application tasks                                 */
    AppTaskCreate();

    /* Task body, always written as an infinite loop.           */
    while (DEF_TRUE) {
        DoSomeWork(...);
        OSTimeDlyHMSM(0, 0, 0, 250);   // Delay for 250 ms
    }
}

//-------------------------------------------------------------------------------------------------------------------

static  void  AppTaskCreate (void)
{
    // Create the application tasks

    OSTaskCreateExt(AppTaskUserIF, ....);
    OSTaskNameSet(APP_TASK_USER_IF_PRIO, "User I/F", &err);

    OSTaskCreateExt(AppTaskKbd, ....);
    OSTaskNameSet(APP_TASK_KBD_PRIO, "Keyboard", &err);

    OSTaskCreateExt(AppTaskFactorial, ...);
    OSTaskNameSet(APP_TASK_FACTORIAL_PRIO, "Factorial", &err);
}

//-------------------------------------------------------------------------------------------------------------------

static  void  AppTaskKbd (void *p_arg)
{
    // Monitor the state of the push buttons and passes messages to AppTaskUserIF()

    while (DEF_TRUE)
    {
        joystick = Joystick_GetStatus();

        OSMboxPost(AppUserIFMbox1, (void *)joystick);

        OSTimeDly(OS_TICKS_PER_SEC / 10);
    }
}

//-------------------------------------------------------------------------------------------------------------------


static  void  AppTaskUserIF (void *p_arg)
{
    // LCD updating task

    // Initialize the LCD module
    PowerUp_LCD(NULL);

    while (DEF_TRUE) {

        msg = OSMboxPend(AppUserIFMbox1, OS_TICKS_PER_SEC / 10, &err);
        msg = OSMboxAccept(AppUserIFMbox2);

        Write_To_LCD_Cmd(msg);
    }
}

//-------------------------------------------------------------------------------------------------------------------


static  void  AppTaskFactorial (void *p_arg)
{
    // Busy task - calculating factorials for fun and profit

    UINT  factorial;
    UINT i = 0;

    while (DEF_TRUE)
    {
        factorial = IntensiveAndExpensiveFactorial(i++ % 50);

        // Give others a chance to run
        OSTimeDlyHMSM(0, 0, 0, 100);
    }
}

Previous topic

uCOS Startup

Next topic

uCOS Port - Review and Notes

This Page